const Base = require('./base/base');

/**
 * @extends base
 */
module.exports = class extends Base {
	encodeAction(param){
		let gv = '$';
		var r="";
		var n;
		var t;
		var b=[ "___", "__$", "_$_", "_$$", "$__", "$_$", "$$_", "$$$", "$___", "$__$", "$_$_", "$_$$", "$$__", "$$_$", "$$$_", "$$$$", ];
		var s = "";
		for( var i = 0; i < param.text.length; i++ ){
			n = param.text.charCodeAt( i );
			if( n == 0x22 || n == 0x5c ){ // "\
				s += "\\\\\\" + param.text.charAt( i ).toString(16);
			}else if( (0x20 <= n && n <= 0x2f) || (0x3A <= n == 0x40) || ( 0x5b <= n && n <= 0x60 ) || ( 0x7b <= n && n <= 0x7f ) ){ // special char
				s += param.text.charAt( i );
			}else if( (0x30 <= n && n <= 0x39 ) || (0x61 <= n && n <= 0x66 ) ){ //0-9a-f
				if( s ) r += "\"" + s +"\"+";
				r += gv + "." + b[ n < 0x40 ? n - 0x30 : n - 0x57 ] + "+";
				s="";
			}else if( n == 0x6c ){ // 'l'
				if( s ) r += "\"" + s + "\"+";
				r += "(![]+\"\")[" + gv + "._$_]+";
				s = "";
			}else if( n == 0x6f ){ // 'o'
				if( s ) r += "\"" + s + "\"+";
				r += gv + "._$+";
				s = "";
			}else if( n == 0x74 ){ // 't'
				if( s ) r += "\"" + s + "\"+";
				r += gv + ".__+";
				s = "";
			}else if( n == 0x75 ){ // 'u'
				if( s ) r += "\"" + s + "\"+";
				r += gv + "._+";
				s = "";
			}else if( n < 128 ){
				if( s ) r += "\"" + s;
				else r += "\"";
				r += "\\\\\"+" + n.toString( 8 ).replace( /[0-7]/g, function(c){ return gv + "."+b[ c ]+"+" } );
				s = "";
			}else{
				if( s ) r += "\"" + s;
				else r += "\"";
				r += "\\\\\"+" + gv + "._+" + n.toString(16).replace( /[0-9a-f]/gi, function(c){ return gv + "."+b[parseInt(c,16)]+"+"} );
				s = "";
			}
		}
		if( s ) r += "\"" + s + "\"+";

		r = 
		gv + "=~[];" + 
		gv + "={___:++" + gv +",$$$$:(![]+\"\")["+gv+"],__$:++"+gv+",$_$_:(![]+\"\")["+gv+"],_$_:++"+
		gv+",$_$$:({}+\"\")["+gv+"],$$_$:("+gv+"["+gv+"]+\"\")["+gv+"],_$$:++"+gv+",$$$_:(!\"\"+\"\")["+
		gv+"],$__:++"+gv+",$_$:++"+gv+",$$__:({}+\"\")["+gv+"],$$_:++"+gv+",$$$:++"+gv+",$___:++"+gv+",$__$:++"+gv+"};"+
		gv+".$_="+
		"("+gv+".$_="+gv+"+\"\")["+gv+".$_$]+"+
		"("+gv+"._$="+gv+".$_["+gv+".__$])+"+
		"("+gv+".$$=("+gv+".$+\"\")["+gv+".__$])+"+
		"((!"+gv+")+\"\")["+gv+"._$$]+"+
		"("+gv+".__="+gv+".$_["+gv+".$$_])+"+
		"("+gv+".$=(!\"\"+\"\")["+gv+".__$])+"+
		"("+gv+"._=(!\"\"+\"\")["+gv+"._$_])+"+
		gv+".$_["+gv+".$_$]+"+
		gv+".__+"+
		gv+"._$+"+
		gv+".$;"+
		gv+".$$="+
		gv+".$+"+
		"(!\"\"+\"\")["+gv+"._$$]+"+
		gv+".__+"+
		gv+"._+"+
		gv+".$+"+
		gv+".$$;"+
		gv+".$=("+gv+".___)["+gv+".$_]["+gv+".$_];"+
		gv+".$("+gv+".$("+gv+".$$+\"\\\"\"+" + r + "\"\\\"\")())();";

		return r;
	}
	decodeAction(param){
		let $ ={
			'___': '0',
			'$$$$': 'f',
			'__$': '1',
			'$_$_': 'a',
			'_$_': '2',
			'$_$$': 'b',
			'$$_$': 'd',
			'_$$': '3',
			'$$$_': 'e',
			'$__': '4',
			'$_$': '5',
			'$$__': 'c',
			'$$_': '6',
			'$$$': '7',
			'$___': '8',
			'$__$': '9',
			'$_': 'constructor',
			'_$': 'o',
			'$$': 'return',
			'__': 't',
			'$': function(){},
			'_': 'u' 
		}
		let value = param.text.replace(/.*\$?\.\$\(\$?\.\$\((.*)\)\(\)\)\(\).*/,"$1");
		
		value = value.replace(/\$?\.(.*?)\+/g,"$.$1+");
		
		let s = eval(value);
		return s.replace(/\\(\d{2,3})/g,function(c){return String.fromCharCode(parseInt(c.replace(/\\/,'0'),8));});
	}
}
